#pragma once

/**
 * 对 listen_fd 进行管理
 *
 */

#include "Channel.h"
#include "Socket.h"

namespace devem {

// 打包成 Channel
using ConnectionCallback = std::function<void(int)>;

class Acceptor {
public:
    Acceptor(EventLoop* loop)
        : loop_(loop), listen_fd_(CreateServer()), socket_(listen_fd_), channel_(listen_fd_, loop_) {
        // channel_.EnableRead();
        channel_.SetReadCallBack(std::bind(&Acceptor::HandleRead, this));
    }

    void HandleRead() {
        std::string client_ip;
        uint16_t client_port;
        int fd = socket_.Accept(&client_ip, &client_port);
        if (fd < 0)
            return;
        LOG_DEBUG("accept a new link:[%s:%u]", client_ip, client_port);
        conn_callback_(fd);
    }

    int CreateServer() {
        if (!socket_.CreateServer()) {
            LOG_WARN("acceptor create fail.");
        }
        return socket_.Fd();
    }

    void SetConnCallback(const ConnectionCallback& conn_callback) { conn_callback_ = conn_callback; }

    void StartListen() { channel_.EnableRead(); }

private:
    int listen_fd_;
    Socket socket_;
    EventLoop* loop_;
    Channel channel_;
    ConnectionCallback conn_callback_;
};
}  // namespace devem